import { Request, Response } from 'express';
import UserModel from '../models/User';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import { config as dotEnvConfig } from 'dotenv';

//执行后可以使用全局.env文件内定义的属性
dotEnvConfig();
//通过`process.env`属性获取`.env`里定义的内容。
const { SECRET_KEY } = process.env;

export interface IUserInfo {
  username: string;
  password: string;
}

export async function getUserList(req: Request, res: Response) {
  const users = await UserModel.getUserList();
  res.status(200).json(users);
}

export async function register(req: Request, res: Response) {
  const { username, password }: IUserInfo = req.body;

  //捕获username字段定义唯一字段时返回的异常错误
  try {
    //向数据库发起新增用户操作
    const user = await UserModel.addUser({ username, password });
    res.status(200).json({
      err_code: 0,
      err_msg: 'addUser successfully!',
      data: user
    });
  } catch (e) {
    res.status(200).json({
      err_code: 1002,
      err_msg: 'The username existed in database'
    });
  }
}

export async function login(req: Request, res: Response) {
  const { username, password }: IUserInfo = req.body;

  //查询指定的用户信息
  const userInfo = await UserModel.getUser(username);
  if (!userInfo) {
    return res.status(200).json({
      err_code: 1003,
      err_msg: 'The username dost not exist in database.'
    });
  }
  //对比指定用户密码是否正确 用户输入的密码与数据库中加密过的密码进行比对
  //userInfo.password! 写法为 TS非运行时推断时认为有可能为undefined 非空断言 排除null undefined
  const isValidPassword = bcrypt.compareSync(password, userInfo.password!);
  //如果不是合法的密码时
  if (!isValidPassword) {
    return res.status(200).json({
      err_code: 1004,
      err_msg: 'Got a wrong password.'
    });
  }
  //服务器管理私钥 前端用户拿到的是公钥和私钥结合后的结果
  //jwt.sign(可选的自定义字符串, 服务器提供的私钥, 过期时间)
  const accessToken = jwt.sign({ id: String(userInfo._id) }, SECRET_KEY!, {
    expiresIn: '60s'
  });
  //密码正确时返回信息
  res.status(200).json({
    err_code: 0,
    err_msg: 'login successfully!',
    data: {
      username: userInfo.username,
      level: userInfo.level,
      access_token: accessToken
    }
  });
}

export async function getProfile(req: Request, res: Response) {
  const { id } = req;
  const userInfo = await UserModel.getProfile(id!);

  res.status(200).json({
    err_code: 0,
    err_msg: 'GetProfile successfully!',
    data: userInfo
  });
}

export async function checkLogin(req: Request, res: Response) {
  res.status(200).json({
    err_code: 0,
    err_msg: 'checkLogin successfully!'
  });
}
